<script lang="ts" setup>
import SearchPlace from '@/components/map/SearchPlace.vue'
import ShowPoint from '@/components/map/ShowPoint.vue'
import { reactive, ref, onMounted, shallowRef, onActivated } from 'vue'
import { useMap } from '@/hooks/useMap'
import { useRoute } from 'vue-router'
import { useMapPoint } from '@/store/modules/mapPoint'
import ReturnImg from '@/assets/map/showPointAMap/return.png'
import TakeImg from '@/assets/map/showPointAMap/bind.png'
import StorePointImg from '@/assets/map/showPointAMap/storepoint.png'
import TimePointImg from '@/assets/map/showPointAMap/timepoint.png'
import LocationImg from '@/assets/map/showPointAMap/location.png'
import { BindAndReturnAddressType } from '@/types/interface'
import { useActivated } from '@/hooks/useActivated'
import { copyEvent } from '@/utils'
defineOptions({
  name: 'ShowPointAMap'
})
const route = useRoute()
const { getTakeAddress, getReturnAddress, getType, getReturnIsArray, getTakeIsArray } =
  useMapPoint()
const params = reactive({
  name: route.query.name as string,
  type: getType()
})
const center = reactive({
  longtitude: 0,
  latitude: 0
})
const isInit = ref<boolean>(false)
const mapContainer = ref<HTMLDivElement>()
/** 还车点标注图层 */
const returnLabelsLayer = shallowRef<AMap.LabelsLayer>()
/** 取车点标注图层 */
const takeLabelsLayer = shallowRef<AMap.LabelsLayer>()
/** 还车点标注点 用于添加进图层 */
const returnLabelMarkers = shallowRef<AMap.LabelMarker[]>([])
/** 取车点标注点 用于添加进图层 */
const takeLabelMarkers = shallowRef<AMap.LabelMarker[]>([])
/** 还车点覆盖物群组 */
const returnOverLayerGroup = shallowRef<AMap.OverlayGroup>()
/** 取车点覆盖物群组 */
const takeOverLayerGroup = shallowRef<AMap.OverlayGroup>()
const { map, auto, initAmap, placeSearch } = useMap(mapContainer, [
  center.longtitude,
  center.latitude
])
/** 地图初始化 */
const init = async () => {
  isInit.value = await initAmap()
  handleCoverInit()
}
const getReturnIcon: () => AMap.LabelMarkerIconOptions = () => {
  return {
    type: 'image', //图标类型，现阶段只支持 image 类型
    image: ReturnImg, //可访问的图片 URL
    size: [40, 48], //图片尺寸
    clipOrigin: [0, 0],
    clipSize: [40, 48]
  }
}
const getTakeIcon: () => AMap.LabelMarkerIconOptions = () => {
  return {
    type: 'image', //图标类型，现阶段只支持 image 类型
    image: TakeImg, //可访问的图片 URL
    size: [40, 48], //图片尺寸
    clipOrigin: [0, 0],
    clipSize: [40, 48]
  }
}
const handleCoverInit = () => {
  if (!(isInit.value && map.value)) return
  resetMap()
  handleInitReturnLabelsLayer()
  handleInitBindLabelsLayer()
  const mapContainer = document.getElementById('map-container')
  mapContainer?.addEventListener('click', handleInfoWindowClick)
  takeLabelsLayer.value?.hide()
  returnLabelsLayer.value?.hide()
  returnOverLayerGroup.value?.hide()
  takeOverLayerGroup.value?.hide()
  controlShowLayer()
}
/** 初始化还车点图层 */
const handleInitReturnLabelsLayer = () => {
  /** 获取还车点数据 */
  const returnAddress = getReturnAddress()
  /** 获取还车点数据是否数组 */
  const returnisArray = getReturnIsArray()
  /** 初始化图层 */
  returnLabelsLayer.value = new AMap.LabelsLayer({
    zooms: [3, 20],
    zIndex: 1000,
    collision: false, //该层内标注是否避让
    allowCollision: true //不同标注层之间是否避让
  })
  /** 初始化覆盖物群组 */
  returnOverLayerGroup.value = new AMap.OverlayGroup()
  /** 将图层添加进地图实例 */
  map.value?.add(returnLabelsLayer.value)
  /** 判断数据是否为数组/对象 */
  if (returnisArray) {
    ;(returnAddress as BindAndReturnAddressType[]).forEach((point) => {
      const curpoint = {
        position: new AMap.LngLat(Number(point.longtitude) ?? 0, Number(point.latitude) ?? 0),
        icon: getReturnIcon(),
        rank: 1,
        zIndex: 16
      }
      /** 实例化标注点 */
      const labelMarker = new AMap.LabelMarker(curpoint)
      /** 实例化弹框 */
      const marker = new AMap.Marker({
        map: map.value!,
        position: new AMap.LngLat(Number(point.longtitude) ?? 0, Number(point.latitude) ?? 0),
        content: createContent(point),
        anchor: 'bottom-center',
        topWhenClick: true,
        offset: [0, -50]
      })
      /** 将标注点添加进还车点标注组 */
      returnLabelMarkers.value.push(labelMarker)
      /** 将弹框添加进覆盖物群组 */
      returnOverLayerGroup.value?.addOverlay(marker)
    })
    returnLabelsLayer.value.add(returnLabelMarkers.value)
  } else {
    /** 同理 */
    const labelMarker = new AMap.LabelMarker({
      position: new AMap.LngLat(
        Number((getReturnAddress() as BindAndReturnAddressType).longtitude) ?? 0,
        Number((getReturnAddress() as BindAndReturnAddressType).latitude) ?? 0
      ),
      icon: getReturnIcon(),
      rank: 1,
      zIndex: 16
    })
    const marker = new AMap.Marker({
      map: map.value!,
      position: new AMap.LngLat(
        Number((getReturnAddress() as BindAndReturnAddressType).longtitude) ?? 0,
        Number((getReturnAddress() as BindAndReturnAddressType).latitude) ?? 0
      ),
      content: createContent(getReturnAddress() as BindAndReturnAddressType),
      anchor: 'bottom-center',
      topWhenClick: true,
      offset: [0, -50]
    })
    returnLabelMarkers.value.push(labelMarker)
    returnLabelsLayer.value.add(returnLabelMarkers.value)
    returnOverLayerGroup.value?.addOverlay(marker)
  }
}
/**初始化取车点图层 同理*/
const handleInitBindLabelsLayer = () => {
  const takeAddress = getTakeAddress()
  const takeisArray = getTakeIsArray()
  takeLabelsLayer.value = new AMap.LabelsLayer({
    zooms: [3, 20],
    zIndex: 1000,
    collision: true, //该层内标注是否避让
    allowCollision: true //不同标注层之间是否避让
  })
  takeOverLayerGroup.value = new AMap.OverlayGroup()
  map.value?.add(takeLabelsLayer.value)
  if (takeisArray) {
    ;(takeAddress as BindAndReturnAddressType[]).forEach((point) => {
      const curpoint = {
        position: new AMap.LngLat(Number(point.longtitude) ?? 0, Number(point.latitude) ?? 0),
        icon: getTakeIcon(),
        rank: 1,
        zIndex: 16
      }
      const marker = new AMap.Marker({
        map: map.value!,
        position: new AMap.LngLat(Number(point.longtitude) ?? 0, Number(point.latitude) ?? 0),
        content: createContent(point),
        anchor: 'bottom-center',
        topWhenClick: true,
        offset: [0, -50]
      })
      const labelMarker = new AMap.LabelMarker(curpoint)
      takeLabelMarkers.value.push(labelMarker)
      takeOverLayerGroup.value?.addOverlay(marker)
    })
    takeLabelsLayer.value.add(takeLabelMarkers.value)
  } else {
    const labelMarker = new AMap.LabelMarker({
      position: new AMap.LngLat(
        Number((getTakeAddress() as BindAndReturnAddressType).longtitude) ?? 0,
        Number((getTakeAddress() as BindAndReturnAddressType).latitude) ?? 0
      ),
      icon: getTakeIcon(),
      rank: 1,
      zIndex: 16
    })
    const marker = new AMap.Marker({
      map: map.value!,
      position: new AMap.LngLat(
        Number((getTakeAddress() as BindAndReturnAddressType).longtitude) ?? 0,
        Number((getTakeAddress() as BindAndReturnAddressType).latitude) ?? 0
      ),
      content: createContent(getTakeAddress() as BindAndReturnAddressType),
      anchor: 'bottom-center',
      topWhenClick: true,
      offset: [0, -50]
    })
    takeLabelMarkers.value.push(labelMarker)
    takeLabelsLayer.value.add(takeLabelMarkers.value)
    takeOverLayerGroup.value.addOverlay(marker)
  }
}
/** 控制图层及覆盖物群组的显示 并获取到中心点并设置 */
const controlShowLayer = () => {
  if (getType() === 'return') {
    takeLabelsLayer.value?.hide()
    takeOverLayerGroup.value?.hide()
    returnLabelsLayer.value?.show()
    returnOverLayerGroup.value?.show()
    const firstPoint = returnLabelMarkers.value[0]
    center.longtitude = firstPoint.getPosition().getLng()
    center.latitude = firstPoint.getPosition().getLat()
  } else {
    returnLabelsLayer.value?.hide()
    returnOverLayerGroup.value?.hide()
    takeLabelsLayer.value?.show()
    takeOverLayerGroup.value?.show()
    const firstPoint = takeLabelMarkers.value[0]
    center.longtitude = firstPoint.getPosition().getLng()
    center.latitude = firstPoint.getPosition().getLat()
  }
  map.value?.setCenter([center.longtitude, center.latitude])
}
/** 判断是否点击复制 */
const handleInfoWindowClick = (event: any) => {
  if (event.target.className.includes('red-copy')) {
    copyEvent(event.target.dataset.address)
  }
}
const createContent = (data: BindAndReturnAddressType) => {
  return `
                       <div class="take-or-return-point">
                        <div class="take-or-return-point__title">
                          <img src="${StorePointImg}"/>
                          <span>${data.name}</span>
                        </div>
                        <div class="take-or-return-point__address">
                           <img src="${LocationImg}"/>
                           <div>
                              <span>${data.address}</span>
                              <span class="red-copy" data-address=${data.address}>复制</span>
                           </div>
                        </div>
                        <div class="take-or-return-point__service">
                         <img src="${TimePointImg}"/>
                          <span>服务时间 :  ${data.serviceTime}</span>
                        </div>
                      </div>
                    `
}
/** 清空 */
const resetMap = () => {
  /** 将覆盖物群组中的覆盖物 从地图中清除 */
  returnOverLayerGroup.value?.eachOverlay((overlay) => {
    overlay.setMap(null)
  })
  takeOverLayerGroup.value?.eachOverlay((overlay) => {
    overlay.setMap(null)
  })
  /** 将覆盖物群组清空 */
  takeOverLayerGroup.value?.clearOverlays()
  returnOverLayerGroup.value?.clearOverlays()
  /** 将标注点数组清空 */
  takeLabelMarkers.value = []
  returnLabelMarkers.value = []
  /** 将图层清空 */
  returnLabelsLayer.value?.clear()
  takeLabelsLayer.value?.clear()
  /** 将图层从地图清除 */
  map.value?.removeLayer(returnLabelsLayer.value!)
  map.value?.removeLayer(takeLabelsLayer.value!)
}
onActivated(() => {
  params.name = route.query.name as string
  params.type = getType()
})
/** 处理是否缓存 */
useActivated(
  params,
  { params },
  [
    { key: 'name', path: 'params.name' },
    { key: 'type', path: 'params.type' }
  ],
  handleCoverInit,
  []
)

onMounted(() => {
  init()
})
</script>

<template>
  <div class="xy-map-container">
    <div ref="mapContainer" id="map-container">
      <search-place :auto="auto" :map="map!" :place-search="placeSearch" />
      <show-point @change="controlShowLayer" />
    </div>
  </div>
</template>

<style scoped lang="scss">
:deep(.take-or-return-point) {
  background: #fff;
  box-shadow: 0px 0px 30px rgba(0, 0, 0, 0.06);
  border-radius: 5px;
  display: flex;
  flex-direction: column;
  padding: 10px;
  .take-or-return-point__title {
    font-size: 13px;
    font-family: PingFang SC;
    font-weight: 500;
    line-height: 18px;
    color: #000000;
    margin-bottom: 10px;
    display: flex;
    align-items: center;
  }
  .take-or-return-point__address {
    display: flex;
    align-items: center;
    margin-bottom: 8px;
    > div {
      font-size: 12px;
      font-family: PingFang SC;
      line-height: 14px;
      color: #999999;
      display: flex;
      flex-direction: row;
      justify-content: flex-start;
      .red-copy {
        color: #ff6d75;
        cursor: pointer;
      }
    }
  }
  .take-or-return-point__service {
    display: flex;
    align-items: center;
    > span {
      font-size: 12px;
      font-family: PingFang SC;
      line-height: 14px;
      color: #333333;
    }
    img {
      margin-left: 3px;
    }
  }
  img {
    margin-right: 5px;
  }
  span {
    white-space: nowrap;
  }
}
</style>
